Empezaremos esta práctica con algo de conocimientos previos de programación. Se que muchos de ustedes no han tenido la oportunidad de utilizar Python como lenguaje de programación y mucho menos IPython como ambiente de desarrollo para computo cientifico, asi que el primer objetivo de esta práctica será acostumbrarnos a la sintaxis del lenguaje y a las funciones que hacen especial a IPython.
Primero tratemos de evaluar una expresión aritmetica. Para correr el código en la siguiente celda, tan solo tienes que hacer clic en cualquier punto de ella y presionar las teclas Shift + Return.
In [ ]:
2 + 2
En la linea de arriba es facil ver que cualquier calculo aritmetico que hagamos, simplemente lo podemos escribir en una linea de código y IPython nos dará la respuesta.
In [ ]:
sin(pi)
La linea anterior nos permite ver que si iniciamos correctamente nuestro ambiente de desarrollo:
ipython notebook --pylab inline
las funciones trigonometricas, asi como las constantes importantes para matemáticas, estarán cargadas tambien.
Otra manera de obtener estas funciones, es mandarlas llamar con el comando import (asi es como lo hariamos en un script normal de Python).
In [ ]:
from math import sin, pi
sin(pi)
Las listas son una manera de guardar varios datos en un mismo arreglo. Podemos tener por ejemplo:
In [ ]:
A = [2, 4, 8, 10]
Pero si intentamos multiplicar estos datos por un numero, no tendrá el comportamiento esperado.
In [ ]:
A*2
Podemos definir funciones propias de la siguiente manera:
In [ ]:
f = lambda x: x**2 + 1
Esta linea de codigo es equivalente a definir una función matemática de la siguiente manera:
$$f(x) = x^2 + 1$$Por lo que si la evaluamos con $x = 2$, obviamente obtendremos como resultado $5$.
In [ ]:
f(2)
Esta notación que introducimos es muy util para funciones matemáticas, pero esto nos obliga a pensar en las definiciones de una manera funcional, lo cual no siempre es la solución (sobre todo en un lenguaje con un paradigma de programación orientado a objetos).
Esta función tambien puede ser escrita de la siguiente manera:
In [ ]:
def g(x):
return x**2 + 1
Con los mismos resultados:
In [ ]:
g(2)
Cuando queremos ejecutar código varias veces tenemos varias opciones, vamos a explorar rapidamente el ciclo for.
for paso in pasos:
...
codigo_a_ejecutar(paso)
...
En este caso el codigo se ejecutará tantas veces sean necesarias para usar todos los elementos que hay en pasos.
Por ejemplo, pordemos ejecutar la multiplicacion por 2 en cada uno de los datos:
In [ ]:
for dato in A:
print dato*2
ó agregarlo en una lista nueva:
In [ ]:
B = []
for dato in A:
B.append(dato*2)
B
Pero esto es impractico, hay una estructura que nos puede ayudar llamada
matrix()
In [ ]:
C = matrix([2, 4, 8, 10])
In [ ]:
C*2
y aun muchas cosas mas, pero por ahora es momento de empezar con la práctica.
Las matrices de rotación y traslación nos sirven para transformar una coordenada entre diferentes sistemas coordenados, pero tambien lo podemos ver, como la transformación que le hace cada eslabon a nuestro punto de ubicación.
Empecemos con la rotación:
$$ R_z = \begin{pmatrix} \cos{\theta} & - \sin{\theta} & 0 & 0 \\ \sin{\theta} & \cos{\theta} & 0 & 0\\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix} $$La matriz que escribimos, girará nuestro de eje de coordenadas con respecto al eje $z$ un angulo $\theta$. Por cierto, las funciones trigonometricas toman como argumento el angulo en radianes, por lo que tomaré la convencion de llamar a $\tau = 2 \pi$, para definir los angulos como fracciones de la vuelta completa.
In [ ]:
tau = 2*pi
Podemos definir vectores columna y matrices de la siguiente manera, y podremos ver que el resultado es lo que esperariamos si quisieramos rotar el vector unitario $\hat{i}$, $30º = \frac{\tau}{12}$.
In [ ]:
r_1 = matrix([[1],
[0],
[0],
[1]])
R_z = matrix([[cos(tau/12), -sin(tau/12), 0, 0],
[sin(tau/12), cos(tau/12), 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]])
R_z*r_1
Pero podemos hacer algo mejor, podemos definir una función que nos devuelva una matriz de rotación, dandole como argumento el angulo de rotación.
In [ ]:
def matrotz(theta):
return matrix([[cos(theta), -sin(theta), 0, 0], [sin(theta), cos(theta), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
Entonces, tendremos el mismo resultado, con un codigo mas limpio.
In [ ]:
rot1 = matrotz(tau/12)
rot1*r_1